home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-01 / wtek0693.zip / OOPALLEY.ZIP / TIMECLS.CPP < prev    next >
C/C++ Source or Header  |  1993-04-28  |  8KB  |  252 lines

  1. #include "date.h"
  2. #include "timecls.h"
  3. #include "oopsconfig.h"
  4.  
  5. #define THIS    Time
  6. #define BASE    Object
  7. DEFINE_CLASS(Time,Object);
  8. ////////////////////////////////////////////////////////////
  9. //  class Time
  10. //  Provides an object that represents
  11. //  a Time, stored as the number of
  12. //  seconds since January 1, 1901, GMT.
  13. ////////////////////////////////////////////////////////////
  14.  
  15. #include <time.h>
  16. #define TIME_ZONE timezone
  17. #define DST_OBSERVED daylight
  18.  
  19.  
  20.  
  21. //-gmv remove static for debugging
  22. /*static*/ const unsigned long seconds_in_day = 24L*60*60; //-gmv made long
  23. /*static*/ const Date refDate(0);
  24. /*static*/ const Date maxDate(49709);   // ((2**32)-1)/seconds_in_day -1 
  25.     
  26. //////////////////////////////////////////////////
  27. // Return a local Time for the specified
  28. // Standard Time date, hour, minute, and second.
  29. //////////////////////////////////////////////////
  30. static Time localTime(const Date& date, hourTy h=0, minuteTy m=0, secondTy s=0)
  31. {
  32.     if (!date.between(refDate,maxDate))
  33.         DTerror("Date out  of range: ", "");
  34.     return Time(seconds_in_day*(date-refDate) + 60*60L*h + 60*m + s);
  35. }
  36.  
  37. //////////////////////////////////////////////////
  38. //  Construct a Time for this instant
  39. //////////////////////////////////////////////////
  40. Time::Time()                      
  41. {
  42.     sec += 2177452800L;         // seconds from 1/1/01 to 1/1/70 
  43. }
  44.  
  45. //////////////////////////////////////////////////
  46. //  update Time for this instant
  47. //////////////////////////////////////////////////
  48. void Time::update()             
  49. {
  50.     sec += 2177452800L;         // seconds from 1/1/01 to 1/1/70
  51. }
  52.  
  53. //////////////////////////////////////////////////
  54. //  Construct a Time for today at
  55. //  the specified (local) hour,
  56. //  minute, and second.
  57. //////////////////////////////////////////////////
  58. Time::Time(hourTy h, minuteTy m, secondTy s, bool dst)
  59. {
  60.     sec = Time(Date(),h,m,s,dst).sec;
  61. }
  62.  
  63.  
  64. //////////////////////////////////////////////////
  65. //  Construct a Time for
  66. //  the specified (local) Date, hour,
  67. //  minute, and second.
  68. //////////////////////////////////////////////////
  69. Time::Time(const Date& date, hourTy h, minuteTy m, secondTy s, bool dst)
  70. {
  71.     sec = ::localTime(date,h,m,s).sec;
  72.     if (isDST()) {
  73.         if (isDST() || dst) sec -= 3600;
  74.     }
  75.     else {
  76.         if (isDST())
  77.             DTerror("Invalid date/time: ", "");
  78.     }
  79.     sec += TIME_ZONE;               // adjust to GMT
  80. }
  81.  
  82. //////////////////////////////////////////////////
  83. //  Convert a Time to a local Date
  84. //////////////////////////////////////////////////
  85. #ifdef DATE_CAST
  86. Time::operator Date() const
  87. #else
  88. Date Time::getDate() const
  89. #endif
  90.  
  91. {
  92.     clockTy daycount = localTime().sec/seconds_in_day;
  93.     return Date(daycount);
  94. }
  95.  
  96. //////////////////////////////////////////////////
  97. //  Return the hour of this Time
  98. //  in local time; i.e., adjust for
  99. //  time zone and Daylight Savings Time.
  100. //////////////////////////////////////////////////
  101. hourTy Time::hour() const
  102. {
  103.     return localTime().hourGMT();
  104. }
  105.  
  106. //////////////////////////////////////////////////
  107. //  Return the hour of this Time in GMT.
  108. //////////////////////////////////////////////////
  109. hourTy Time::hourGMT() const
  110. {
  111.     return (hourTy)((sec % 86400L) / 3600L);
  112. }
  113.  
  114. //////////////////////////////////////////////////
  115. //  Return the local Standard Time
  116. //  at which Daylight Savings Time
  117. //  begins in the specified year.
  118. //////////////////////////////////////////////////
  119. static Time beginDST(unsigned year)
  120. {
  121.     Time DSTtime(localTime(Date(31,"Mar",year).previous("Sun")+7,2));
  122.     if (year<=1986) {
  123.         DSTtime = localTime(Date(30,"Apr",year).previous("Sun"),2);
  124.         if (year==1974) DSTtime = localTime(Date(6,"Jan",1974),2);
  125.         if (year==1975) DSTtime = localTime(Date(23,"Feb",1975),2);
  126.     }
  127.     return DSTtime;
  128. }
  129.  
  130. //////////////////////////////////////////////////
  131. //  Return the local Standard Time
  132. //  at which Daylight Savings Time
  133. //  ends in the specified year.
  134. //////////////////////////////////////////////////
  135. static Time endDST(unsigned year)
  136. {
  137.     Time STDtime(localTime(Date(31,"Oct",year).previous("Sun"),2-1));
  138.     return STDtime;
  139. }
  140.  
  141. //////////////////////////////////////////////////
  142. //  Return YES if this local Standard Time
  143. //  should be adjusted for Daylight Savings Time.
  144. //////////////////////////////////////////////////
  145. bool Time::isDST() const
  146. {
  147.     int daycount = this->sec/seconds_in_day;
  148.     unsigned year = Date(daycount).year();
  149.     if (DST_OBSERVED && *this >= beginDST(year) && *this < endDST(year)) 
  150.         return YES;
  151.     return NO;
  152. }
  153.  
  154. //////////////////////////////////////////////////
  155. //  Adjusts this GM Time for local
  156. //  time zone and Daylight Savings Time.
  157. //////////////////////////////////////////////////
  158. Time Time::localTime() const
  159. {
  160.     Time local_time(sec-TIME_ZONE);
  161.     if (local_time.isDST()) local_time.sec += 3600;
  162.     return local_time;
  163. }
  164.  
  165. //////////////////////////////////////////////////
  166. //  Return the minute of this Time        
  167. //  in local time; i.e., adjust for       
  168. //  time zone and Daylight Savings Time.  
  169. //////////////////////////////////////////////////
  170. minuteTy Time::minute() const
  171. {
  172.     return localTime().minuteGMT();
  173. }
  174.  
  175. //////////////////////////////////////////////////
  176. //  Return the minute of this Time in GMT.  
  177. //////////////////////////////////////////////////
  178. minuteTy Time::minuteGMT() const
  179. {
  180.     return ((sec % 86400L) % 3600L) / 60L;
  181. }
  182.  
  183. //////////////////////////////////////////////////
  184. //  Return the second of this Time.
  185. //////////////////////////////////////////////////
  186. secondTy Time::second() const
  187. {
  188.     return ((sec % 86400L) % 3600L) % 60L;
  189. }
  190.  
  191. Time Time::max(Time t) const
  192. {
  193.     if (t.sec < sec)
  194.         return *this;
  195.     else
  196.         return t;
  197. }
  198.  
  199. Time Time::min(Time t) const
  200. {
  201.     if (t.sec > sec)
  202.         return *this;
  203.     else
  204.         return t;
  205. }
  206.  
  207. int Time::compare(const Object& ob) const
  208. {
  209.     assertArgSpecies(ob,class_Time,"compare");
  210.     register clockTy t = ((Time*)&ob)->sec;
  211.     if (sec < t) return -1;
  212.     if (sec > t) return 1;
  213.     return 0;
  214. }
  215.  
  216. Object*         Time::copy() const          { return shallowCopy(); }
  217. void            Time::deepenShallowCopy()   {}
  218. unsigned        Time::hash() const          { return sec; }
  219. bool            Time::isEqual(const Object& ob) const
  220.                 {
  221.                     return ob.isSpecies(class_Time) && *this==*(Time*)&ob;
  222.                 }
  223. const Class*    Time::species() const       { return &class_Time; }
  224. void            Time::printOn(ostream& strm) const
  225.                 {
  226.                     unsigned hh = hour();
  227. #ifdef DATE_CAST
  228.                     ((Date)*this).printOn(strm);
  229. #else
  230.                     getDate().printOn(strm);
  231.                     cout << " ";
  232. #endif
  233.                     char saveFillChar = strm.fill();
  234.                     long saveFlags = strm.flags();
  235.  
  236.                     strm.width(2);
  237.                     strm.fill(' ');
  238.                     strm << ((hh <= 12) ? hh : hh-12) << ":";
  239.                     strm.width(2);
  240.                     strm.fill('0');
  241.                         strm << minute() << ":";
  242.                     strm.width(2);
  243.                     strm.fill('0');
  244.                     strm << second();
  245.  
  246.                     strm.fill(saveFillChar);
  247.                     strm.flags(saveFlags);
  248.                     if (hh < 12) strm << " am";
  249.                     else strm << " pm";
  250. }
  251.  
  252.